import { AppRequest } from "../../wrap/request";
import { EmptyRequest } from "@/utils/network/engine/error";
import { addToast2Queue } from "@/utils/toastQueue";

import type { RequestDefaultConfig } from "../../request.type";
import type { CommonRes } from "@/typings/common";
import type { ErrorResponse } from "@/utils/network/engine/types/InnerRequestConfig";

export interface UseRequestResArr {
    run: () => Promise<CommonRes<any>[]>;
    request: AppRequest[];
}
export interface UseRequestRes {
    run: () => Promise<CommonRes<any>>;
    request: AppRequest;
}

// 当个请求
const _singleRequest = async (
    req: AppRequest,
    complete: (uuid: string) => void
): Promise<CommonRes<any, ErrorResponse>> => {
    // 执行
    let thisUUID = req.uuid;
    try {
        let response = await req.run();
        let { res } = response || {};
        complete(thisUUID);
        return [undefined, res];
    } catch (error) {
        let errResponse = error as ErrorResponse;
        complete(thisUUID);
        return [errResponse, undefined];
    }
};

// 启动请求
async function _runWithRequestArr(requestArr: AppRequest[], removeReq: (uuid: string) => void) {
    if (requestArr.length === 0) {
        let emptyCB: CommonRes<any> = [new EmptyRequest(), undefined];
        return [emptyCB];
    }
    // 启动promise
    let promiseArr = requestArr.map((e) => {
        return _singleRequest(e, (uuid) => {
            // 请求完成, 要删除uuid
            removeReq(uuid);
        });
    });
    let resArr = await Promise.all(promiseArr);
    // 返回的
    let callBackRes: CommonRes<any>[] = [];
    // 遍历 处理错误
    for (let i = 0; i < resArr.length; i++) {
        let single = resArr[i];
        if (single[0]) {
            // 有错误
            let { err, config } = single[0];
            if (config.autoHandleError) {
                // 显示 toast
                addToast2Queue(err.errMsg);
            }
            callBackRes.push([err, single[1]]);
        } else {
            // 没有错误
            callBackRes.push(single);
        }
    }
    return callBackRes;
}

// 请求
function APIRequest<T extends RequestDefaultConfig[]>(
    reqArr: T,
    pushReq: (item: AppRequest) => void,
    removeReq: (uuid: string) => void
): UseRequestResArr | UseRequestRes {
    // 循环创建 添加
    let requestArr = [] as AppRequest[];
    for (let i = 0; i < reqArr.length; i++) {
        let c = reqArr[i];
        let req = AppRequest.request(c);
        // 添加
        pushReq(req);
        requestArr.push(req);
    }
    let requestLength = requestArr.length;
    const _runSingle = async (): Promise<CommonRes<any>> => {
        let arr = await _runWithRequestArr(requestArr, removeReq);
        return arr[0];
    };
    // 请求
    const _runArr = async (): Promise<CommonRes<any>[]> => {
        return await _runWithRequestArr(requestArr, removeReq);
    };

    // 判断长度
    if (requestLength >= 2) {
        return {
            request: requestArr,
            run: _runArr,
        };
    } else {
        let result: UseRequestRes = {
            request: requestArr[0],
            run: _runSingle,
        };
        return result;
    }
}

export { APIRequest };
